package middleware

import (
	"context"
  "strconv"
	"happy-sudoku/internal/codec"
	logging "happy-sudoku/internal/infr"

	"github.com/99designs/gqlgen/graphql"
	"github.com/pkg/errors"
	"github.com/vektah/gqlparser/gqlerror"
)

// GQLErrorPresenter is the error handler middleware for graphql
func GQLErrorPresenter(ctx context.Context, e error) *gqlerror.Error {
	logger := logging.ForLoggerContext(ctx)

	errCause := errors.Cause(e)

	if code, ok := errCause.(codec.Code); ok {
		path := graphql.GetResolverContext(ctx).Path()
		if codec.IsInternalError(errCause) {
			code = codec.InternalError
			logger.Error(e.Error())
			// Print Error Stack if Internal Error
			logger.Errorf("%+v", e)
		} else {
			logger.Warn(e.Error())
		}

		return &gqlerror.Error{
			Message: code.Message(),
			Extensions: map[string]interface{}{
				"code":      strconv.Itoa(code.Code()),
				"root-code": code.RootCode(),
				"name":      code.Name(),
			},
			Path: path,
		}
	}

	logger.Warn(e.Error())
	return graphql.DefaultErrorPresenter(ctx, e)
}
